package com.tubang.organization.shiro;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.tubang.component.entity.UserEntity;
import com.tubang.component.service.IUserService;
import com.tubang.organization.entity.MenuEntity;
import com.tubang.organization.entity.RoleEntity;
import com.tubang.organization.entity.RoleMenuEntity;
import com.tubang.organization.entity.UserRoleEntity;
import com.tubang.organization.service.IMenuService;
import com.tubang.organization.service.IRoleMenuService;
import com.tubang.organization.service.IRoleService;
import com.tubang.organization.service.IUserRoleService;

/**
 * @ClassName MyShiroRealm
 * @Description TODO
 * @author wsl
 * @date 2017年11月30日 上午8:21:23
 */
public class MyShiroRealm extends AuthorizingRealm {
	private Logger logger = LoggerFactory.getLogger(getClass());

	@Resource
	private IUserService userService;
	@Resource
	private IUserRoleService userRoleService;
	@Resource
	private IRoleService roleService;
	@Resource
	private IRoleMenuService roleMenuService;
	@Resource
	private IMenuService menuService;

	// 认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) throws AuthenticationException {
		// 获取用户的输入的用户名
		UsernamePasswordToken token = (UsernamePasswordToken) at;
		String username = token.getUsername();
		logger.info("method[doGetAuthenticationInfo],登录用户名为：{}", username);

		UserEntity userDto = new UserEntity();
		userDto.setMobile(username);
		EntityWrapper<UserEntity> entityWrapper = new EntityWrapper<>(userDto);
		// 查询用户
		UserEntity user = userService.selectOne(entityWrapper);

		if (user == null) {
			logger.info("method[doGetAuthenticationInfo] 没有找到该用户,用户名为：{}", username);
			return null;
		}
		// 账户不可用，被锁定
		if (!user.getEnable()) {
			throw new LockedAccountException("账号被锁定：enable值为0");
		}

		//ByteSource.Util.bytes(username), 
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
				user.getMobile(), // 用户名
				user.getPassword(), // 密码
				getName() // realm name
		);
		
		return authenticationInfo;
	}

	// 授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		UserEntity user = (UserEntity) SecurityUtils.getSubject().getPrincipal();
		if (null == user) {
			return null;
		}
		/* 
		 * User{id=1, username='admin',
		 * password='3ef7164d1f6167cb9f2658c07d3c2f0a',
		 * enable=1}
		 */
		
		//根据用户id获取用户roleid
		UserRoleEntity userRole = new UserRoleEntity();
		userRole.setUserId(user.getId());		
		EntityWrapper<UserRoleEntity>  userRoleEntity= new EntityWrapper<>(userRole);
		List<UserRoleEntity> userRoles = userRoleService.selectList(userRoleEntity);
		
		// 权限信息对象info,用来存放查出的用户的所有的角色（role）及权限（permission）
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		
		getUserPermission(userRoles, info);
		return info;
	}

	private void getUserPermission(List<UserRoleEntity> userRoles, SimpleAuthorizationInfo info) {
		//根据roleid获取menuid
		for (UserRoleEntity ur : userRoles) {
			RoleEntity role = new RoleEntity();
			role.setId(ur.getRoleId());
			EntityWrapper<RoleEntity> roleEntity = new EntityWrapper<>(role);
			List<RoleEntity> roles = roleService.selectList(roleEntity);
			for (RoleEntity r : roles) {
				RoleMenuEntity roleMenu = new RoleMenuEntity();
				roleMenu.setRoleId(r.getId());
				EntityWrapper<RoleMenuEntity> roleMenuEntity = new EntityWrapper<>(roleMenu);
				List<RoleMenuEntity> roleMenus = roleMenuService.selectList(roleMenuEntity);
				for (RoleMenuEntity rm : roleMenus) {
					MenuEntity menu = new MenuEntity();
					menu.setId(rm.getMenuId());
					menu.setType("2");
					EntityWrapper<MenuEntity> menuEntity = new EntityWrapper<>(menu);
					List<MenuEntity> menusTemp = menuService.selectList(menuEntity);
					//去重
					List<MenuEntity> menus = new ArrayList<MenuEntity>(new HashSet<MenuEntity>(menusTemp));
					for (MenuEntity m : menus) {
						if (StringUtils.isNotBlank(m.getFunction())){
							// 添加基于Permission的权限信息
							info.addStringPermission(m.getFunction());
						}
					}
				}
			}
		}
	}

	/**
	 * 指定principalCollection 清除
	 */
	/*
	 * public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection) {
	 * 
	 * SimplePrincipalCollection principals = new SimplePrincipalCollection( principalCollection, getName());
	 * super.clearCachedAuthorizationInfo(principals); }
	 */

}
